package cz.muni.fi.pv168.confusinglibrary;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;

public class BookManagerImpl implements BookManager {
	private List<Book> books;
	private long idCount = 0;
	
	public BookManagerImpl() {
		books = new ArrayList<Book>();
	}

	@Override
	public Book addBook(Book book) {
		if (book == null) {
            throw new NullPointerException("book");
        }
        
		book.setId(idCount++);
		books.add(book);
		return book;
	}

	@Override
	public void removeBook(Book book) {
		if (book == null) {
            throw new NullPointerException("book");
        }
		if (book.getId() == null) {
            throw new NullPointerException("book id");
        }
        
		Iterator<Book> it = books.iterator();
		while (it.hasNext()) {
			Book thisBook = it.next();
			if (book.getId().equals(thisBook.getId())) {
				it.remove();
			}
		}
	}

	@Override
	public Book updateBook(Book book) {
		if (book == null) {
            throw new NullPointerException("book");
        }
		if (book.getId() == null) {
            throw new NullPointerException("book id");
        }
        
		Book updatedBook = null;
		Iterator<Book> it = books.iterator();
		
		while (it.hasNext()) {
			Book thisBook = it.next();
			if (book.getId().equals(thisBook.getId())) {
				thisBook.setAuthor(book.getAuthor());
				thisBook.setName(book.getName());
				thisBook.setDescription(book.getDescription());
				thisBook.setFiction(book.isFiction());
				thisBook.setPublished(book.getPublished());
				updatedBook = thisBook;
			}
		}
		return updatedBook;
	}

	@Override
	public List<Book> getAllBooks() {
		return Collections.unmodifiableList(books);
	}

	@Override
	public Book findBookById(Long id) {
		if (id != null) {
			for (Book book : books) {
				if (id.equals(book.getId())) {
					return book;
				}
			}
		}
		return null;
	}

	@Override
	public List<Book> findBooksByName(String name) {
		if (name != null) {
			List<Book> booksByName = new ArrayList<Book>();
			
			for (Book book : books) {
				if (name.equals(book.getName())) {
					booksByName.add(book);
				}
			}
			return booksByName;
		}
		return null;
	}

	@Override
	public List<Book> findBooksByAuthor(Author author) {
		if (author != null) {
			List<Book> booksByAuthor = new ArrayList<Book>();
			
			for (Book book : books) {
				if (author.equals(book.getAuthor())) {
					booksByAuthor.add(book);
				}
			}
			return booksByAuthor;
		}
		return null;
	}
	
}
